package dto

import (
	"strings"

	"code.bydev.io/cht/customer/kyc_admin_service/internal/pkg/kycadminapi/dto"
)

type AdminAction int

const (
	AdminActionInit     AdminAction = 0 // 初始状态
	AdminActionCreate   AdminAction = 1 // 创建回调
	AdminActionPending  AdminAction = 2 // 等待状态
	AdminActionComplete AdminAction = 3 // 完成
	AdminActionReset    AdminAction = 4 // 重置
)

func GetBizDecisionCnDesc(d dto.Decision, a AdminAction) string {
	switch a {
	case AdminActionCreate, AdminActionPending:
		return "认证中"
	case AdminActionInit:
		return "申请"
	}
	if d.IsBizSuccess() {
		return "通过"
	}
	if d.IsBizReject() {
		return "失败"
	}
	return "未知"
}

func GetBizDecisionEnDesc(d dto.Decision, a AdminAction) string {
	switch a {
	case AdminActionInit, AdminActionCreate: // 初始状态
		return "UNSUBMIT"
	case AdminActionPending: // 等待状态
		return "UNDER REVIEW"
	case AdminActionComplete: // 完成
		if d.IsBizSuccess() {
			return "APPROVED"
		}
		if d.IsBizReject() {
			return "REJECTED"
		}
	case AdminActionReset: // 重置
		return "RESET"
	}
	return "UNKNOWN"
}

func GetProviderDecisionCnDesc(pd int8) string {
	switch dto.Decision(pd) {
	case dto.DecisionSuccess:
		return "通过"
	case dto.DecisionReject:
		return "失败"
	}
	return "未知"
}

func GetProviderDecisionEnDesc(pd int8) string {
	switch dto.Decision(pd) {
	case dto.DecisionSuccess:
		return ReviewResultEnPass.String()
	case dto.DecisionReject:
		return ReviewResultEnReject.String()
	}
	return ReviewResultEnUnknown.String()
}

// KYCProvider provider types
// NOTE: 新通道标记
type KYCProvider int

const (
	// ProviderSumSub sumsub
	ProviderUnknown KYCProvider = iota
	ProviderSumSub  KYCProvider = 1
	ProviderJumio   KYCProvider = 2
	ProviderOnfido  KYCProvider = 3
)

func GetAllKYCProviders() []KYCProvider {
	return []KYCProvider{
		ProviderSumSub,
		ProviderJumio,
		ProviderOnfido,
	}
}

func (k KYCProvider) IsUnknown() bool {
	return k == ProviderUnknown
}

func (k KYCProvider) IsProviderSumSub() bool {
	return k == ProviderSumSub
}

func (k KYCProvider) IsProviderJumio() bool {
	return k == ProviderJumio
}

func (k KYCProvider) IsProviderOnfido() bool {
	return k == ProviderOnfido
}

func GetProvider(s string) KYCProvider {
	switch s {
	case "sumsub":
		return ProviderSumSub
	case "jumio":
		return ProviderJumio
	case "onfido":
		return ProviderOnfido
	default:
		return ProviderSumSub
	}
}

func (k KYCProvider) String() string {
	switch k {
	case ProviderSumSub:
		return "sumsub"
	case ProviderJumio:
		return "jumio"
	case ProviderOnfido:
		return "onfido"
	default:
		return "sumsub"
	}
}

func (k KYCProvider) Upper() string {
	return strings.ToUpper(k.String())
}

// KYCLevel enums
type KYCLevel int

const (
	LevelDefault             KYCLevel = iota // 默认KYC等级 = 0
	Level1                                   // KYC Level1等级 = 1
	Level2                                   // KYC Level2等级 = 2
	Level1Camera                             // 只用于sumsub通道,证件只允许拍照提交
	Level1BVN                                // 只用于sumsub通道,BVN
	Level2BVN                                // 只用于sumsub通道,BVN LV2
	Level1SecondaryDL                        // 驾照第二证件
	Level1SecondaryDLCamera                  // 驾照第二证件,证件只允许拍照提交
	Level1SecondaryBVN                       // BVN第二证件
	Level1SecondaryBVNCamera                 // BVN第二证件,证件只允许拍照提交
	Level1SecondaryID                        // 身份证第二证件
	Level1SecondaryIDCamera                  // 身份证第二证件,证件只允许拍照提交
	Level1SecondaryPP                        // 护照第二证件
	Level1SecondaryPPCamera                  // 护照第二证件,证件只允许拍照提交
	Level1SecondaryRP                        // 居住证第二证件
	Level1SecondaryRPCamera                  // 居住证第二证件,证件只允许拍照提交
	Level2Secondary                          // 第二证明
	Level1Secondary                          // 第二证件
	Level1SecondaryIDRU                      // (白)俄罗斯身份证第二证件
	Level1SecondaryPPRU                      // (白)俄罗斯护照第二证件
	KYCLevel1Third                           // 第三认证
	POISupplementPreDoc                      // 补充证件
	POISupplement                            // 第二证件补充人脸
	FSMPOISupplementPreDoc                   // fsm POISupplementPreDoc
	FSMPOISupplement                         // fsm POISupplement
	KYCLevel2POA                             // KYC 新Level2等级
	KYCLevel2POASupplement                   // KYC 新第二Level2等级
)

// !NOTE: make sure to correspond with production config
func (l KYCLevel) String() string {
	switch l {
	case Level1:
		return "Level1"
	case Level2:
		return "Level2"
	case Level1Camera:
		return "Level1_camera"
	case Level1BVN:
		return "BVN_check"
	case Level2BVN:
		return "BVN_check_advanced"
	case Level2Secondary:
		return "Level2_advanced"
	case Level1SecondaryBVN:
		return "Level1_a_bvn"
	case Level1SecondaryBVNCamera:
		return "Level1_a_bvn_camera"
	case Level1SecondaryID:
		return "Level1_a_id"
	case Level1SecondaryIDCamera:
		return "Level1_a_id_camera"
	case Level1SecondaryPP:
		return "Level1_a_pp"
	case Level1SecondaryPPCamera:
		return "Level1_a_pp_camera"
	case Level1SecondaryDL:
		return "Level1_a_dl"
	case Level1SecondaryDLCamera:
		return "Level1_a_dl_camera"
	case Level1SecondaryRP:
		return "Level1_a_rp"
	case Level1SecondaryRPCamera:
		return "Level1_a_rp_camera"
	case Level1Secondary:
		return "Level1_advanced"
	case Level1SecondaryIDRU:
		return "Level1_a_id_ru_by"
	case Level1SecondaryPPRU:
		return "Level1_a_pp_ru_by"
	case KYCLevel1Third:
		return "Level1_third"
	case POISupplementPreDoc:
		return "POI_Supplement_pre"
	case POISupplement:
		return "POI_Supplement"
	case KYCLevel2POA:
		return "POA"
	case KYCLevel2POASupplement:
		return "POA_Supplement"
	default:
		return "Level1"
	}
}

type SerialType int

const (
	SerialTypePrimary SerialType = iota
	SerialTypeSecondary
)

func LvlNameIsSecondary(lvlName string) bool {
	switch lvlName {
	case Level1SecondaryDL.String(),
		Level1SecondaryDLCamera.String(),
		Level1SecondaryBVN.String(),
		Level1SecondaryBVNCamera.String(),
		Level1SecondaryID.String(),
		Level1SecondaryIDCamera.String(),
		Level1SecondaryPP.String(),
		Level1SecondaryPPCamera.String(),
		Level1SecondaryRP.String(),
		Level1SecondaryRPCamera.String(),
		Level2Secondary.String(),
		Level1Secondary.String(),
		Level1SecondaryIDRU.String(),
		Level1SecondaryPPRU.String(),
		POISupplementPreDoc.String(),
		POISupplement.String(),
		KYCLevel2POASupplement.String():
		return true
	}

	return false
}

func LvlNameIsSupplement(lvlName string) bool {
	switch lvlName {
	case POISupplementPreDoc.String(), POISupplement.String(), KYCLevel2POASupplement.String():
		return true
	default:
		return false
	}
}

func GetUnifiedLevel(levelName string) KYCLevel {
	switch levelName {
	case Level1.String(), Level1Camera.String(), Level1BVN.String(), Level1SecondaryDL.String(),
		Level1SecondaryDLCamera.String(), Level1SecondaryBVN.String(), Level1SecondaryBVNCamera.String(),
		Level1SecondaryPP.String(), Level1SecondaryPPCamera.String(), Level1SecondaryID.String(),
		Level1SecondaryIDCamera.String(), Level1SecondaryRP.String(), Level1SecondaryRPCamera.String(), Level1Secondary.String(),
		Level1SecondaryIDRU.String(), Level1SecondaryPPRU.String(), POISupplementPreDoc.String(), POISupplement.String():
		return Level1
	case Level2.String(), Level2BVN.String(), Level2Secondary.String(), KYCLevel2POA.String(), KYCLevel2POASupplement.String():
		return Level2
	default:
		return Level1
	}
}

type ApplicantState int

const (
	ApplicantCreated ApplicantState = iota
	ApplicantPending
	ApplicantReviewed
	ApplicantReset
)

// ReviewState state machine
type ReviewState int

const (
	// StateInit created
	StateInit ReviewState = iota
	// StatePending pending
	StatePending
	// StateComplete done
	StateComplete
	// StateReset reseted
	StateReset
	// StateDelete delete
	StateDelete
)

type BanType int

const (
	// BanDefault 默认，未封禁
	BanDefault BanType = iota
	// BanUserLogin 登录封禁
	BanUserLogin
	// BanWithDraw 提现封禁
	BanWithDraw
	// BanWithTrade 交易封禁
	BanWithTrade
)

func (r ReviewState) IsInit() bool {
	return r == StateInit || r == StateReset
}

func (r ReviewState) IsComplete() bool {
	return r == StateComplete
}

func (r ReviewState) IsPending() bool {
	return r == StatePending || r.IsInit()
}

func (r ReviewState) CanReset() bool {
	return r != StateReset
}

// ReviewResult yes or not
type ReviewResult int

const (
	// ReviewResultUnknown default
	ReviewResultUnknown ReviewResult = iota
	// ReviewResultPass pass
	ReviewResultPass
	// ReviewResultReject failed
	ReviewResultReject
)

func (r ReviewResult) IsPassed() bool {
	return r == ReviewResultPass
}

func (r ReviewResult) IsReject() bool {
	return r == ReviewResultReject
}

type ReviewResultEn string

const (
	ReviewResultEnUnknown ReviewResultEn = "Unknown"
	ReviewResultEnPass    ReviewResultEn = "Passed"
	ReviewResultEnReject  ReviewResultEn = "Reject"
)

func (re ReviewResultEn) String() string {
	return string(re)
}

type KYCType int

const (
	KYCTypeIndividual KYCType = 0
	KYCTypeCompany    KYCType = 1
)

// Limitation limitations
type Limitation int

const (
	// LimitationNone no limit
	LimitationNone Limitation = iota
	// LimitationDemond kyc required by cs
	LimitationDemond
	// LimitationWorldCheck WorldCheck
	LimitationWorldCheck
	// LimitationBan ban
	LimitationBan
)

type DocumentType string

const (
	DocumentTypeUnknown   DocumentType = "unknown"
	DocumentTypeID        DocumentType = "id_card"
	DocumentTypePassport  DocumentType = "passport"
	DocumentTypeDriver    DocumentType = "driver"
	DocumentTypeResidence DocumentType = "residence"
	DocumentTypeSelfie    DocumentType = "selfie"
	DocumentTypeBank      DocumentType = "bank_card"
	DocumentTypeBill      DocumentType = "bill"
	DocumentTypeBVN       DocumentType = "BVN"
)

// IsValidIdentityType 是否是有效证件类型
func (l DocumentType) IsValidIdentityType() bool {
	return l == DocumentTypeID ||
		l == DocumentTypePassport ||
		l == DocumentTypeDriver ||
		l == DocumentTypeResidence ||
		string(l) == DocumentTypeResidence.String()
}

func (l DocumentType) String() string {
	switch l {
	case DocumentTypeUnknown:
		return "unknown"
	case DocumentTypeID:
		return "id_card"
	case DocumentTypePassport:
		return "passport"
	case DocumentTypeDriver:
		return "driver"
	case DocumentTypeResidence:
		return "recidence"
	case DocumentTypeSelfie:
		return "selfie"
	case DocumentTypeBank:
		return "bank_card"
	case DocumentTypeBill:
		return "bill"
	case DocumentTypeBVN:
		return "BVN"
	default:
		return "Level1"
	}
}

func (l DocumentType) ToSourceType() string {
	switch l {
	case DocumentTypeUnknown:
		return "unknown"
	case DocumentTypeID:
		return "ID_CARD"
	case DocumentTypePassport:
		return "PASSPORT"
	case DocumentTypeDriver:
		return "DRIVERS"
	case DocumentTypeResidence:
		return "RESIDENCE_PERMIT"
	case DocumentTypeSelfie:
		return "SELFIE"
	case DocumentTypeBank:
		return "BANK_CARD"
	case DocumentTypeBill:
		return "UTILITY_BILL"
	case DocumentTypeBVN:
		return "BVN"
	default:
		return "unknown"
	}
}

type Gender = string

const (
	GenderUnknown Gender = "unknown"
	GenderMale    Gender = "male"
	GenderFemale  Gender = "female"
)

const CantRetry = -1

type TopicID int32

const (
	LevelOnePass TopicID = iota + 1001
	LevelOneReject
	LevelTwoPass
	LevelTwoReject
)

type DocType int

const (
	UndefinedDocType DocType = iota
	ID
	Passport
	DrivingLicense
	LivingPermits
	Bill
	DocTypeCC
	DocTypeBS
	DocTypeIC
	DocTypeUB
	DocTypeCAAP
	DocTypeCRC
	DocTypeCCS
	DocTypeLAG
	DocTypeLOAP
	DocTypeMOAP
	DocTypeTR
	DocTypeVT
	DocTypeVC
	DocTypeSTUC
	DocTypeHCC
	DocTypeCB
	DocTypeSENC
	DocTypeMEDC
	DocTypeBC
	DocTypeWWCC
	DocTypeSS
	DocTypeTAC
	DocTypeSEL
	DocTypePB
	DocTypeSSC
	DocTypeCUSTOM
	DocTypeOTHER
	BVN
)

type SubDocType int

const (
	UndefinedSubDocType SubDocType = iota
	NationalID
	ConsularID
)

func (sdt SubDocType) String() string {
	switch sdt {
	case UndefinedSubDocType:
		return string(SubTypeDescUndefined)
	case NationalID:
		return string(SubTypeDescNationalID)
	case ConsularID:
		return string(SubTypeDescConsularID)
	}

	return string(SubTypeDescUndefined)
}

type SubTypeDesc string

const (
	SubTypeDescNationalID SubTypeDesc = "NATIONAL_ID"
	SubTypeDescConsularID SubTypeDesc = "CONSULAR_ID"
	SubTypeDescUndefined  SubTypeDesc = ""
)

func (st SubTypeDesc) GetSubType() SubDocType {
	switch st {
	case SubTypeDescNationalID:
		return NationalID
	case SubTypeDescConsularID:
		return ConsularID
	}
	return UndefinedSubDocType
}

type SecondRejectLabel string

const (
	ReuseDocuments SecondRejectLabel = "REUSE_DOCUMENTS"
)

type SumsubValidity string

const (
	SumsubValiditySelfieMismatch SumsubValidity = "SELFIE_MISMATCH"
	SumsubValidityBadSelfie      SumsubValidity = "BAD_SELFIE"
	SumsubValidityBadVideoSelfie SumsubValidity = "BAD_VIDEO_SELFIE"
	SumsubValidityBadFaceMatch   SumsubValidity = "BAD_FACE_MATCHING"
)

type SumsubSimilarity string

const (
	SumsubSimilarityFraudulent SumsubSimilarity = "FRAUDULENT_LIVENESS"
)

const (
	ImageTagFront    string = "FRONT"
	ImageTagBack     string = "BACK"
	ImageTagLiveness string = "LIVENESS_3"
	ImageTagFace     string = "FACE"
)
